"Outside option member", "Cooperative member",
"Outside option member", "Cooperative member") # variable names to appear in plots
coef3 <- seregfa[,1]
coef3 <- unname(coef3[c(2,3)])
coef3a <- sereg5[,1]
coef3a <- unname(coef3a[c(2,3)])
coef3b <- sereg7[,1]
coef3b <- unname(coef3b[c(2,3)])
coef3c <- sereg9[,1]
coef3c <- unname(coef3c[c(2,3)])
coef3d <- sereg12[,1]
coef3d <- unname(coef3d[c(2,3)])
coef3e <- sereg11[,1]
coef3e <- unname(coef3e[c(2)])
coef3g <- sereg6[,1]
coef3g <- unname(coef3g[c(2,3)])
coef3h <- sereg15[,1]
coef3h <- unname(coef3h[c(2,3)])
coef3i <- sereg17[,1]
coef3i <- unname(coef3i[c(2,3)])
coef3j <- sereg19[,1]
coef3j <- unname(coef3j[c(2,3)])
coef3k <- sereg21[,1]
coef3k <- unname(coef3k[c(2,3)])
coef3l <- sereg23[,1]
coef3l <- unname(coef3l[c(2,3)])
coef3m <- summary(reg27)$coefficients
coef3m <- unname(coef3m[c(2,3)])
coef3n <- sereg29[,1]
coef3n <- unname(coef3n[c(2,3)])
se3 <- seregfa[,2]
se3 <- unname(se3[c(2,3)])
se3a <- sereg5[,2]
se3a <- unname(se3a[c(2,3)])
se3b <- sereg7[,2]
se3b <- unname(se3b[c(2,3)])
se3c <- sereg9[,2]
se3c <- unname(se3c[c(2,3)])
se3d <- sereg12[,2]
se3d <- unname(se3d[c(2,3)])
se3e <- sereg11[,2]
se3e <- unname(se3e[c(2)])
se3g <- sereg6[,2]
se3g <- unname(se3g[c(2,3)])
se3h <- sereg15[,2]
se3h <- unname(se3h[c(2,3)])
se3i <- sereg17[,2]
se3i <- unname(se3i[c(2,3)])
se3j <- sereg19[,2]
se3j <- unname(se3j[c(2,3)])
se3k <- sereg21[,2]
se3k <- unname(se3k[c(2,3)])
se3l <- sereg23[,2]
se3l <- unname(se3l[c(2,3)])
se3m <- sqrt(diag(vcov(reg27)))
se3m <- unname(se3m[c(2,3)])
se3n <- sereg29[,2]
se3n <- unname(se3n[c(2,3)])
low3 <- coef3 - (1.645*se3)
high3 <- coef3 + (1.645*se3)
low3a <- coef3a - (1.645*se3a)
high3a <- coef3a + (1.645*se3a)
low3b <- coef3b - (1.645*se3b)
high3b <- coef3b + (1.645*se3b)
low3c <- coef3c - (1.645*se3c)
high3c <- coef3c + (1.645*se3c)
low3d <- coef3d - (1.645*se3d)
high3d <- coef3d + (1.645*se3d)
low3e <- coef3e - (1.645*se3e)
high3e <- coef3e + (1.645*se3e)
low3g <- coef3g - (1.645*se3g)
high3g <- coef3g + (1.645*se3g)
low3h <- coef3h - (1.645*se3h)
high3h <- coef3h + (1.645*se3h)
low3i <- coef3i - (1.645*se3i)
high3i <- coef3i + (1.645*se3i)
low3j <- coef3j - (1.645*se3j)
high3j <- coef3j + (1.645*se3j)
low3k <- coef3k - (1.645*se3k)
high3k <- coef3k + (1.645*se3k)
low3l <- coef3l - (1.645*se3l)
high3l <- coef3l + (1.645*se3l)
low3m <- coef3m - (1.645*se3m)
high3m <- coef3m + (1.645*se3m)
low3n <- coef3n - (1.645*se3n)
high3n <- coef3n + (1.645*se3n)
resModel3 <- data.frame(param = varnames,
low2.5 = c(low3, low3a, low3b, low3c, low3d, low3e, low3g, low3h, low3i, low3j,
low3k, low3l, low3m, low3n),
est = c(coef3, coef3a, coef3b, coef3c, coef3d, coef3e, coef3g, coef3h, coef3i, coef3j,
coef3k, coef3l, coef3m, coef3n),
up2.5 = c(high3, high3a, high3b, high3c, high3d, high3e, high3g, high3h, high3i, high3j,
high3k, high3l, high3m, high3n))
resModel3$Model <- modelnames <- c("Selection", "Selection",
"No lag", "No lag",
"Drop Greece", "Drop Greece",
"Year FEs", "Year FEs",
"Drop waivers", "Drop waivers",
"Disagg cooperation",
"No imputation", "No imputation",
"Drop ESM", "Drop ESM",
"Deference control", "Deference control",
"Bilateral controls", "Bilateral controls",
"Weak states", "Weak states",
"World Bank control", "World Bank control",
"Mutlilevel", "Multilevel",
"Region FEs", "Region FEs")
limits <- aes(ymax  = up2.5, ymin = low2.5)
plot3 <- ggplot(resModel3, aes(x=param, y=est, color = Model)) +
geom_pointrange(limits, position=position_dodge(width=0.2)) +
geom_hline(yintercept=0, color="red") +
theme_bw() +
theme(text = element_text(size=22), axis.title.y = element_blank(),
legend.position = "none") +
ylab(NULL) +
coord_flip() +
ggtitle("Conditions") +
theme(plot.title = element_text(hjust = 0.5)) +
scale_x_discrete(limits = rev(levels(as.factor(resModel3$param))))
varnames2 <- c("Outside option member", "Cooperative member",
"Outside option member", "Cooperative member",
"Outside option member", "Cooperative member",
"Outside option member", "Cooperative member",
"Outside option member",
"Outside option member", "Cooperative member",
"Outside option member", "Cooperative member",
"Outside option member", "Cooperative member",
"Outside option member", "Cooperative member",
"Outside option member", "Cooperative member",
"Outside option member", "Cooperative member",
"Outside option member", "Cooperative member",
"Outside option member", "Cooperative member") # variable names to appear in plots
coef4 <- seregfb[,1] # repeat for categories
coef4 <- unname(coef4[c(2,3)])
coef4a <- sereg5a[,1]
coef4a <- unname(coef4a[c(2,3)])
coef4b <- sereg7a[,1]
coef4b <- unname(coef4b[c(2,3)])
coef4c <- sereg9a[,1]
coef4c <- unname(coef4c[c(2,3)])
coef4e <- sereg11a[,1]
coef4e <- unname(coef4e[c(2)])
coef4g <- sereg6a[,1]
coef4g <- unname(coef4g[c(2,3)])
coef4h <- sereg16[,1]
coef4h <- unname(coef4h[c(2,3)])
coef4i <- sereg18[,1]
coef4i <- unname(coef4i[c(2,3)])
coef4j <- sereg20[,1]
coef4j <- unname(coef4j[c(2,3)])
coef4k <- sereg22[,1]
coef4k <- unname(coef4k[c(2,3)])
coef4l <- sereg24[,1]
coef4l <- unname(coef4l[c(2,3)])
coef4m <- summary(reg28)$coefficients
coef4m <- unname(coef4m[c(2,3)])
coef4n <- sereg30[,1]
coef4n <- unname(coef4n[c(2,3)])
se4 <- seregfb[,2]
se4 <- unname(se4[c(2,3)])
se4a <- sereg5a[,2]
se4a <- unname(se4a[c(2,3)])
se4b <- sereg7a[,2]
se4b <- unname(se4b[c(2,3)])
se4c <- sereg9a[,2]
se4c <- unname(se4c[c(2,3)])
se4e <- sereg11a[,2]
se4e <- unname(se4e[c(2)])
se4g <- sereg6a[,2]
se4g <- unname(se4g[c(2,3)])
se4h <- sereg16[,2]
se4h <- unname(se4h[c(2,3)])
se4i <- sereg18[,2]
se4i <- unname(se4i[c(2,3)])
se4j <- sereg20[,2]
se4j <- unname(se4j[c(2,3)])
se4k <- sereg22[,2]
se4k <- unname(se4k[c(2,3)])
se4l <- sereg24[,2]
se4l <- unname(se4l[c(2,3)])
se4m <- sqrt(diag(vcov(reg28)))
se4m <- unname(se4m[c(2,3)])
se4n <- sereg30[,2]
se4n <- unname(se4n[c(2,3)])
low4 <- coef4 - (1.645*se4)
high4 <- coef4 + (1.645*se4)
low4a <- coef4a - (1.645*se4a)
high4a <- coef4a + (1.645*se4a)
low4b <- coef4b - (1.645*se4b)
high4b <- coef4b + (1.645*se4b)
low4c <- coef4c - (1.645*se4c)
high4c <- coef4c + (1.645*se4c)
low4e <- coef4e - (1.645*se4e)
high4e <- coef4e + (1.645*se4e)
low4g <- coef4g - (1.645*se4g)
high4g <- coef4g + (1.645*se4g)
low4h <- coef4h - (1.645*se4h)
high4h <- coef4h + (1.645*se4h)
low4i <- coef4i - (1.645*se4i)
high4i <- coef4i + (1.645*se4i)
low4j <- coef4j - (1.645*se4j)
high4j <- coef4j + (1.645*se4j)
low4k <- coef4k - (1.645*se4k)
high4k <- coef4k + (1.645*se4k)
low4l <- coef4l - (1.645*se4l)
high4l <- coef4l + (1.645*se4l)
low4m <- coef4m - (1.645*se4m)
high4m <- coef4m + (1.645*se4m)
low4n <- coef4n - (1.645*se4n)
high4n <- coef4n + (1.645*se4n)
resModel4 <- data.frame(param = varnames2,
low2.5 = c(low4, low4a, low4b, low4c, low4e, low4g, low4h, low4i, low4j,
low4k, low4l, low4m, low4n),
est = c(coef4, coef4a, coef4b, coef4c, coef4e, coef4g, coef4h, coef4i, coef4j,
coef4k, coef4l, coef4m, coef4n),
up2.5 = c(high4, high4a, high4b, high4c, high4e, high4g, high4h, high4i, high4j,
high4k, high4l, high4m, high4n))
resModel4$Model <- modelnames <- c("Selection", "Selection",
"No lag", "No lag",
"Drop Greece", "Drop Greece",
"Year FEs", "Year FEs",
"Disagg cooperation",
"No imputation", "No imputation",
"Drop ESM", "Drop ESM",
"Deference Control", "Deference Control",
"Bilateral Controls", "Bilateral Controls",
"Weak states", "Weak states",
"World Bank control", "World Bank control",
"Multilevel", "Multilevel",
"Region FEs", "Region FEs")
plot4 <- ggplot(resModel4, aes(x=param, y=est, color = Model)) +
geom_pointrange(limits, position=position_dodge(width=0.2)) +
geom_hline(yintercept=0, color="red") +
theme_bw() +
theme(text = element_text(size=22), axis.title.y = element_blank(),
axis.text.y = element_blank(), legend.position="bottom") +
ylab(NULL) +
coord_flip() +
ggtitle("Categories") +
theme(plot.title = element_text(hjust = 0.5)) +
scale_x_discrete(limits = rev(levels(as.factor(resModel4$param))))
g_legend<-function(a.gplot){
tmp <- ggplot_gtable(ggplot_build(a.gplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)}
mylegend<-g_legend(plot4)
p3 <- grid.arrange(arrangeGrob(plot3 + theme(legend.position="none"),
plot4 + theme(legend.position="none"),
nrow=1),
mylegend, nrow=2, heights=c(10, 2)) # Appears as Figure 2 in paper
####################### Descriptive plots ##################################################
hist(sort(prelimimp$count), xlab = "Number of Conditions", density = 30, col = "blue",
breaks = c(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120), ylab = "Frequency", main = "",
cex.lab=1.5, cex.axis=1.5) # histogram of conditionality to show skewness; Figure A7 in appendix
map <- as.data.frame(cbind(as.character(prelimimp$ccode), as.character(prelimimp$ctry), prelimimp$year, prelimimp$count)) # prep data for map of average conditionality burdens
colnames(map) <- c("ccode", "ctry","year", "count") # change col names
map$count <- as.numeric(as.character(map$count)) # change format
map <- aggregate(list(map$count), by = list(map$ccode, map$ctry), mean) # aggregate into mean counts
colnames(map) <- c("ccode", "ctry", "count") # change col names
maps <- joinCountryData2Map(map, joinCode = "ISO3", nameJoinColumn = "ccode", nameCountryColumn = "ctry") # assign data to map
maps <- subset(maps, continent != "Antarctica")
mapss <- mapCountryData(mapToPlot = maps, nameColumnToPlot = "count", mapRegion = "world",
catMethod = "quantiles", colourPalette = brewer.pal(11, name = "Reds"),
addLegend = FALSE, mapTitle = "")
do.call( addMapLegend, c(mapss, legendWidth=0.5, legendMar = 5))
maps1 <- joinCountryData2Map(map, joinCode = "ISO3", nameJoinColumn = "ccode", nameCountryColumn = "ctry") # plot map
# Figure A6 in appendix
mnp <- aggregate(prelimimp$count, by = list(prelimimp$year), mean) # aggregate data into average counts over time
mnp <- mnp[mnp$Group.1 < 2015,]
plot(mnp, type = "l", xlab = "Year", ylab = "Average Number of Conditions",
cex.lab=1.5, cex.axis=1.5) # plot average conditions over time; Figure A5 in appendix
prelimimp$change <- ifelse(prelimimp$ccode == lag(prelimimp$ccode) &
prelimimp$oomem < lag(prelimimp$oomem), -1,
ifelse(prelimimp$ccode == lag(prelimimp$ccode) &
prelimimp$oomem > lag(prelimimp$oomem), 1, 0)) # plot to show change in oo mem
change <- prelimimp[prelimimp$change != 0,]
change$ctry <- as.character(change$ctry)
panelView(oomem~1, data = change, index = c("ctry","year"), xlab = "Year", ylab = "Country",
ignore.treat = T, legendOff = T, main="",
cex.lab=16, cex.axis=16) # Figure A4 in appendix
prelimimp$change <- ifelse(prelimimp$ccode == lag(prelimimp$ccode) &
prelimimp$coopmem < lag(prelimimp$coopmem), -1,
ifelse(prelimimp$ccode == lag(prelimimp$ccode) &
prelimimp$coopmem > lag(prelimimp$coopmem), 1, 0)) # plot to show change in coop mem
change <- prelimimp[prelimimp$change != 0,]
change <- change[-c(1,4,7),] # delete NA and duplicate rows
change$ctry <- as.character(change$ctry)
panelView(coopmem~1, data = change, index = c("ctry","year"), xlab = "Year", ylab = "Country",
ignore.treat = T, legendOff = T, main="",
cex.lab=16, cex.axis=16) # Figure A3 in appendix
rfash <- read.csv("rfalendshare.csv") # load data on RFA lending, IMF lending to RFA members, and 3 year moving averages
rfashp <- read.csv("rfasharep.csv") # load data with just the moving average shares manually copied from prior sheet
####################### Descriptive stats ########################
covs_desc <- c("Duration", "Number of conditions", "PRGF", "GDPPC", "U.S. aid", "Openness",
"Debt service / exports", "Short-term debt / exports", "FDI / GDP", "Quota",
"UN voting (ideal pt dist from U.S.)", "Polity2", "Checks", "Time from last IMF program",
"Liberal ideology", "Cooperative member", "Outside option member",
"Cooperative amount", "Outside option amount", "Election year",
"War", "UNSC member", "Number of categories") # covariate labels
desc <- read.csv("prelimimp.csv")
desc$stone <- rowSums(desc[,c("DEB","FIN","FP","EXT","RTP","SOE","LAB","PRI","SP","POV",
"INS","ENV","OTH")]>0) # create number of categories variable
desc <- desc[,-c(1:6, 8:9, 11:24, 26, 29, 33:34, 36, 39, 44:53, 58:59)]
stargazer(desc, omit.summary.stat = c("p25", "p75"), digits = 2, style = "ajps",
covariate.labels = covs_desc) # Table A10 in appendix
prelim <- prelim[!duplicated(prelim$ID),]
prelim$loansize <- gsub("(.*),.*", "\\1", prelim$loansize) # remove values after commma
prelim$loansize <- as.numeric(as.character(prelim$loansize)) # change format
prelim$loansize[is.na(prelim$loansize)] <- 0 # make NA loan size zero to allow aggregation
prelimagg <- aggregate(prelim$loansize, by = list(prelim$ctry, prelim$year), FUN = sum) # sum IMF loans by country-year
colnames(prelimagg) <- c("ctry", "year", "imfloans") # change column names
prelimaggflar <- prelimagg[prelimagg$ctry %in% c("Bolivia", "Colombia",	"Costa Rica",	"Ecuador",
"Paraguay",	"Peru",	"Uruguay",	"Venezuela"),] # restrict to FLAR countries
prelimaggflar <- aggregate(prelimaggflar$imfloans, by = list(prelimaggflar$year), FUN = sum) # aggregate by year
prelimaggamf <- prelimagg[prelimagg$ctry %in% c("Jordan",	"Emirates",	"Bahrain",	"Tunisia",	"Algeria",
"Djibouti",	"Saudi Arabia",	"Sudan",	"Syria",
"Somalia",	"Iraq",	"Oman",	"Qatar",	"Comoros",
"Kuwait",	"Lebanon",	"Libya",	"Egypt",	"Morocco",
"Mauritania",	"Yemen"),] # restrict to AMF countries
prelimaggamf <- aggregate(prelimaggamf$imfloans, by = list(prelimaggamf$year), FUN = sum) # aggregate by year
prelimaggefsd <- prelimagg[prelimagg$ctry %in% c("Russia", "Armenia", "Belarus", "Kazakhstan",
"Kyrgyzstan", "Tajikistan"),] # restrict to EFSD countries
prelimaggefsd <- aggregate(prelimaggefsd$imfloans, by = list(prelimaggefsd$year), FUN = sum) # aggregate by year
prelimaggbop <- prelimagg[prelimagg$ctry %in% c("Bulgaria",	"Croatia",	"Czech Republic",	"Denmark",
"Hungary",	"Latvia",	"Poland",	"Romania",	"Sweden",
"United Kingdom"),] # restrict to BoP countries
prelimaggbop <- aggregate(prelimaggbop$imfloans, by = list(prelimaggbop$year), FUN = sum) # aggregate by year
prelimaggesm <- prelimagg[prelimagg$ctry %in% c("Austria", "Belgium", "Cyprus", "Estonia", "Finland",
"France", "Germany", "Greece", "Ireland", "Italy",
"Latvia", "Lithuania", "Luxembourg", "Malta",
"Netherlands", "Portugal", "Slovak Republic",
"Slovenia", "Spain"),] # restrict to ESM countries
prelimaggesm <- aggregate(prelimaggesm$imfloans, by = list(prelimaggesm$year), FUN = sum) # aggregate by year
prelimaggefsm <- prelimagg[prelimagg$ctry %in% c("Austria", "Belgium", "Bulgaria", "Croatia", "Cyprus",
"Czech Republic", "Denmark", "Estonia", "Finland",
"France", "Germany", "Greece", "Hungary", "Ireland", "Italy",
"Latvia", "Lithuania", "Luxembourg", "Malta",
"Netherlands", "Poland", "Portugal", "Romania", "Slovak Republic",
"Slovenia", "Spain", "Sweden", "United Kingdom"),] # restrict to EFSM countries
prelimaggefsm <- aggregate(prelimaggefsm$imfloans, by = list(prelimaggefsm$year), FUN = sum) # aggregate by year
# The data above appear in Tables A4--A9 and were manually inputted
####################### Text analysis ########
##->## Cleaning and preprocessing
conditions <- read.csv("IMF_cond.csv") # load conditions tab from Kentikelenis et al. (2016)
Corpus <- Corpus(VectorSource(conditions$Text)) # convert to corpus
Corpus.clean <- tm_map(Corpus, stripWhitespace) # strip white space
Corpus.clean <- tm_map(Corpus.clean, removePunctuation) # remove punctuation
Corpus.clean <- tm_map(Corpus.clean, tolower) # convert to lower case
dataframe <- data.frame(text=unlist(sapply(Corpus.clean, `[`)), stringsAsFactors=F) # convert to frame
conditions <- cbind(conditions, dataframe) # re-append text to frame
imfsub <- read.csv("prelimimp.csv") # load data on oo and coop IO membership
imfsub <- imfsub[c(6, 54, 55)] # subset to just ID and membership columns
colnames(conditions)[4] <- "ID" # harmonize ID column name with other frame
conditions <- merge(unique(conditions), unique(imfsub), by = c("ID"), all.x = T) # merge cooperation data into text data
coop <- conditions[conditions$coopmem==1,] # frame with just coop observations
comp <- conditions[conditions$oomem==1,] # frame with just comp observations
processed <- textProcessor(conditions$text, metadata = conditions) # process text data
out <- prepDocuments(processed$documents, processed$vocab, processed$meta) # build data
##->## Topic modeling for oo member treatment
imf.multi <- manyTopics(processed$documents, processed$vocab, K = 6:16,
prevalence = ~ coopmem + oomem, max.em.its = 100, runs = 10,
data = processed$meta, seed = 1234) # determine how many topics to use
imf.model <- selectModel(processed$documents, processed$vocab, K=10,
prevalence = ~ oomem + coopmem, max.em.its = 100,
runs=10, data = processed$meta, seed = 1234) # run model with 10 topics for becoming oomem or coopmem
plotModels(imf.model) # 2 is better
imf.model1 <- imf.model$runout[[2]] # select 2
labelTopics(imf.model1) # see most common words for labeling
imf.model1.effect <-  estimateEffect(1:10 ~ oomem + coopmem, imf.model1,
meta=processed$meta, uncertainty = "Global")
summary(imf.model1.effect) # examine which topics are significant
plot(imf.model1.effect, covariate = "oomem", topics = c(1,2,5,7),
method = "difference", cov.value1=1, cov.value2=0, ci.level = 0.95,
xlab = "Change in topical prevalence when joining competitive IO",
main = "", xlim = c(-.05,.05), labeltype = "custom",
custom.labels = c('Tax law','Publications',
'Privatization','Bureaucratic tasks'),
cex.lab=1.5, cex.axis=1.5) # plot topical prevalence for oo member treatment; Figure 3 in text
oo_1 <- findThoughts(imf.model1, texts=processed$meta$text, topics=1, n=15) # look at which topics are representative for each significant topic; the # sign demarcates the ones that will appear in the paper
oo_1$index # Tax law (-)
processed$meta$text[10269] # no granting of exemptions to any company [...] and no renewal of existing exemptions
processed$meta$text[11536] # adopt the new income tax code
processed$meta$text[2818] # adopt [...] tax reform package including elimination of tax exemptions and preferential regimes
oo_2 <- findThoughts(imf.model1, texts=processed$meta$text, topics=2, n=15) # look at which topics are representative for each significant topic; the # sign demarcates the ones that will appear in the paper
oo_2$index # Publications (+)
processed$meta$text[8480] # sign memoranda of understandings to delineate responsibilities
processed$meta$text[1200] # publish financial statements on website
oo_5 <- findThoughts(imf.model1, texts=processed$meta$text, topics=5, n=15) # look at which topics are representative for each significant topic; the # sign demarcates the ones that will appear in the paper
oo_5$index # Privatization (-)
processed$meta$text[7034] # conclusion of at least six contracts for the privatization of either large companies or pools of six companies
processed$meta$text[30350] # privatization of the drilling company sonafor the tapestry weaving company msad and the reinsurance company senre
##->## Topic modeling for coop member treatment
plot(imf.model1.effect, covariate = "coopmem", topics = c(1,2,3,4,7,8,9),
method = "difference", cov.value1=1, cov.value2=0, ci.level = 0.95,
xlab = "Change in topical prevalence when joining cooperative IO",
main = "", xlim = c(-.15,.15), labeltype = "custom",
custom.labels = c('Tax law', 'Publications', 'Public spending', 'External debt payments',
'Foreign exchange policy', 'Bureaucratic tasks',
'Trade policy')) # plot topical prevalence for coop member treatment; Figure 4 in text
plot(imf.model1, type="labels", n = 10, topics=c(1:5,7:10), topic.names = c('Tax law',
'Publications',
'Public spending',
'External debt payments',
'Privatization',
'Foreign exchange policy',
'Bureaucratic tasks',
'Trade policy',
'Monetary policy'
)) # plot key words from conditions (Table A6)
nodes <- read.csv("IMF-NODES.csv", header=T, as.is=T)
links <- read.csv("IMF-EDGES.csv", header=T, as.is=T)
net <- graph_from_data_frame(d=links, vertices=nodes, directed=F)
# Generate colors based on cooperation type:
colrs <- c("gray50", "tomato", "gold")
V(net)$color <- colrs[V(net)$type]
# Compute node degrees (#links) and use that to set node size:
deg <- igraph::degree(net, mode="all")
V(net)$size <- deg
# The labels are currently node IDs.
# Setting them to NA will render no labels:
V(net)$label <- NA
# Set edge width based on weight:
E(net)$width <- E(net)$weight
#change arrow size and edge color:
E(net)$arrow.size <- .2
E(net)$edge.color <- "gray80"
# We can even set the network layout:
graph_attr(net, "layout") <- layout_with_lgl
plot(net, vertex.label=V(net)$media, layout = layout_in_circle)
# Plot different types of cooperation separately
net.m <- net - E(net)[E(net)$type=="cofinance" | E(net)$type=="other"] # another way to delete edges:
net.h <- net - E(net)[E(net)$type=="information" | E(net)$type=="other"] # using the minus operator
# Plot the two links separately:
par(mfrow=c(1,2))
plot(net.h, vertex.color="orange", layout=layout_in_circle, main="Co-financing", vertex.label=V(net)$media)
plot(net.m, vertex.color="lightsteelblue2", layout=layout_in_circle, main="Information Sharing", vertex.label=V(net)$media)
## Plot cooperation over time
par(mfrow=c(1,1))
imfcollab <- read.csv("imf_collab.csv")
mnc <- aggregate(imfcollab$coopagg, by = list(imfcollab$year), sum) # aggregate data into average counts over time
plot(mnc, type = "l", xlab = "Year", ylab = "Total Cooperation",
cex.lab=1.5, cex.axis=1.5) # Figure A1 in appendix
## Plot competition over time
par(mfrow=c(1,1))
mno <- aggregate(prelimimp$oomem, by = list(prelimimp$year), sum) # aggregate data into average counts over time
plot(mno, type = "l", xlab = "Year", ylab = "Total Competition",
cex.lab=1.5, cex.axis=1.5) # Figure A2 in appendix
####################### Which observations are missing? ####
miss <- prelimlag[c(2,3,4,10,25,27,28,30,31,32,35,38,40,41,42,43,54:57,60:63)] # create dataset just with covariates used for analysis
miss$complete <- complete.cases(miss) # create variable for whether observation is complete i.e. no missingness
colMeans(is.na(miss)) # calculate share missing by variable. I should leave proportion neoliberal out of the no imputation model at minimum
miss <- miss[-c(8,9,15)] # drop debt service / exports, short-term debt / exports, and prop neoliberal
miss$complete <- complete.cases(miss) # re-create variable for whether observation is complete i.e. no missingness
miss$incomplete <- 1-miss$complete # recode as incomplete
missctry <- aggregate(miss$incomplete, list(miss$ctry, miss$ccode), FUN = sum) # calculate number of obs missing by country
colnames(missctry) <- c("ctry", "ccode", "numincomplete") # rename cols
missyr <- aggregate(miss$incomplete, list(miss$year), FUN = sum) # calculate number of obs missing by year
colnames(missyr) <- c("year", "numincomplete") # rename cols
missyr <- missyr[-c(38:39),] # cut 2015-16, which are not in the data set
maps <- joinCountryData2Map(missctry, joinCode = "ISO3", nameJoinColumn = "ccode", nameCountryColumn = "ctry") # assign data to map
maps <- subset(maps, continent != "Antarctica")
mapss <- mapCountryData(mapToPlot = maps, nameColumnToPlot = "numincomplete", mapRegion = "world",
catMethod = "quantiles", colourPalette = brewer.pal(5, name = "Reds"),
addLegend = FALSE, mapTitle = "")
do.call( addMapLegend, c(mapss, legendWidth=0.5, legendMar = 5)) # Figure A8 in appendix
plot(missyr, type = "l", xlab = "Year", ylab = "Number of Missing Observations",
cex.lab=1.5, cex.axis=1.5) # plot missing observations over time; Figure A9 in appendix
####################### Network regression ####
## Create datasets
imfcollab <- read.csv("imf_collab.csv") # load hand-coded data on collaboration among emergency lending IOs
imfcollab$coopagg <- imfcollab$cofin + imfcollab$infoshare # code aggregate cooperation to only include inforshare and cofin
imfcollab$coopbin <- 0 # create a binary for cooperation
imfcollab$coopbin[imfcollab$coopagg > 0] <- 1 # code the binary
imfcollab2 <- read.csv("imf_collab_clean.csv") # load data with hand-coded covariates
imfcollab2$memdiff <- abs(imfcollab2$io1nummem - imfcollab2$io2nummem) # calculate differences in memberships
imfcollab2$dyid <- paste(imfcollab2$io1short, imfcollab2$io2short) # assign dyad ID
lagdv1 <- slide(imfcollab2, Var = "infoshare", GroupVar = "dyid",
slideBy = 1, NewVar = 'infosharelag') # create lag variable for infoshare
lagdv2 <- slide(imfcollab2, Var = "cofin", GroupVar = "dyid",
slideBy = 1, NewVar = 'cofinlag') # create lag variable for cofin
imfcollab2 <- cbind(imfcollab2, lagdv1$infosharelag) # merge in first lag
imfcollab2 <- cbind(imfcollab2, lagdv2$cofinlag) # merge in second lag
colnames(imfcollab2)[25] <- "infosharelag" # rename columns
colnames(imfcollab2)[26] <- "cofinlag"
un <- read.csv("unidealpt.csv") # load dyadic UN voting data downloaded from Bailey et al. (2017) in November 2018 V21 https://doi.org/10.7910/DVN/LEJUQZ
imfcollab2$imfbin <- ifelse(imfcollab2$io1short == "IMF", 1, 0) # create binary variable for World Bank involvement
imfcollab2$io1topsh <- as.character(imfcollab2$io1topsh) # change data format to character
imfcollab2$io2topsh <- as.character(imfcollab2$io2topsh)
imfcollab2$hqctry1 <- as.character(imfcollab2$hqctry1)
imfcollab2$hqctry2 <- as.character(imfcollab2$hqctry2)
imfcollab2$io1topshc <- countrycode(imfcollab2$io1topsh, origin = "country.name", destination = "cown") # create country code variables for both shareholder and HQ countries
imfcollab2$io2topshc <- countrycode(imfcollab2$io2topsh, origin = "country.name", destination = "cown")
imfcollab2$idealptsh <- NA # create empty variables for UN distance, alliance ties, and rivalry-peace between leading stakeholders
imfcollab2$idealpthq <- NA # variables are then generated in the loops below
for (i in 1:181) {
un1 <- un$idealpt[un$ccode == imfcollab2$io1topshc[i] & un$year == imfcollab2$year[i]]
un2 <- un$idealpt[un$ccode == imfcollab2$io2topshc[i] & un$year == imfcollab2$year[i]]
imfcollab2$idealptsh[i] <- ifelse(is.numeric(abs(un1 - un2)), abs(un1 - un2),NA)
imfcollab2$idealptsh[i] <- ifelse(imfcollab2$io1topshc == imfcollab2$io2topshc, 0, imfcollab2$idealptsh[i])
} # loop to complete UN voting variables
## Analysis
r1 <- glm.nb(infoshare ~ idealptsh + factor(year), data = imfcollab2)
(ser1 <- coeftest(r1, vcov = vcovHC(r1, type = "HC1", cluster = imfcollab2$dyid))) # calculate SEs
r2 <- glm.nb(cofin ~ idealptsh + factor(year), data = imfcollab2)
(ser2 <- coeftest(r2, vcov = vcovHC(r2, type = "HC1", cluster = imfcollab2$dyid))) # calculate SEs
stargazer(r1,r2, se = list(ser1[,2], ser2[,2]),
dep.var.labels = c("Information Sharing", "Co-financing"),
covariate.labels = c("UN voting (ideal pt dist)", "Year"),
style = "ajps", omit = c("Constant","year"), add.lines = yearfe,
omit.stat = c("ll", "aic", "theta")) # Table A11 in appendix
sink()
